package com.plian.system.service.zcgl.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.entity.zcgl.JzsgjgbaEntity;
import com.plian.system.mapper.zcgl.JzsgjgbaMapper;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.zcgl.IJzsgjgbaService;
import com.plian.system.vo.zcgl.JzsgjgbaVO;
import com.plian.system.wrapper.util.CacheWrapperUtil;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author ffl
 */
@Service
public class JzsgjgbaServiceImpl extends BaseServiceImpl<JzsgjgbaMapper, JzsgjgbaEntity> implements IJzsgjgbaService, BaseFlowService {
    private FormWorkflowService formWorkflowService;
    private IFormCodeService formCodeService;
    private FileService fileService;
    private CacheWrapperUtil cacheWrapperUtil;


    public JzsgjgbaServiceImpl(FormWorkflowService formWorkflowService, IFormCodeService formCodeService, FileService fileService, CacheWrapperUtil cacheWrapperUtil) {
        this.formWorkflowService = formWorkflowService;
        this.formCodeService = formCodeService;
        this.fileService = fileService;
        this.cacheWrapperUtil = cacheWrapperUtil;
    }

    @Override
    public boolean add(JzsgjgbaEntity entity) {
        entity.setStatus(FormStatusConstant.UNREVIEWED);
        entity.setCode(formCodeService.getCode(FormTypeConstant.ZCGL_JZSGJGBA_FORM));
        entity.setFormType(String.valueOf(FormTypeConstant.ZCGL_JZSGJGBA_FORM));
        boolean result = this.save(entity);
        fileService.saveAll(String.valueOf(entity.getId()), entity.getDocList());
        HashMap<String, Object> processVariable = new HashMap<>();
        formWorkflowService.startProcessAndSimulate(String.valueOf(entity.getId()), entity.getFormType(), processVariable);
        return result;
    }

    @Override
    public boolean edit(JzsgjgbaEntity entity) {
        boolean result = this.updateById(entity);
        fileService.edit(String.valueOf(entity.getId()), entity.getDocList());
        HashMap<String, Object> processVariable = new HashMap<>();
        formWorkflowService.startProcessAndSimulate(String.valueOf(entity.getId()), entity.getFormType(), processVariable);
        return result;
    }

    @Override
    public boolean remove(List<Long> ids) {
        return this.deleteLogic(ids);
    }

    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    @Override
    public Boolean finish(String id) {
        /**
         * 设置审批人和审批时间
         */
        JzsgjgbaEntity entity = getById(id);
        entity.setApprovedUser(TokenUtil.getTokenUserId());
        Date now = DateUtil.now();
        entity.setApprovedTime(now);
        updateById(entity);

        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), FormStatusConstant.UNREVIEWED);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        List<JzsgjgbaEntity> list = list(new LambdaQueryWrapper<JzsgjgbaEntity>().in(JzsgjgbaEntity::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA))));
        List<JzsgjgbaVO> vos = new ArrayList<>();
        list.forEach(entity -> {
            JzsgjgbaVO vo = new JzsgjgbaVO();
            BeanUtil.copyProperties(entity, vo);
            vo.setCreateUserName(cacheWrapperUtil.userIdToName(entity.getCreateUser()));
            vo.setApprovedUserName(cacheWrapperUtil.userIdToName(entity.getApprovedUser()));
            vo.setUpdateUserName(cacheWrapperUtil.userIdToName(entity.getUpdateUser()));
            vo.setReportCompanyName(cacheWrapperUtil.orgIdToName(entity.getReportCompanyId()));
            vos.add(vo);
        });
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(vos)) {
                for (JzsgjgbaVO vo : vos) {
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getReportCompanyName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getReportCompanyId());
                    pd.put("formType", FormTypeConstant.ZCGL_JZSGJGBA_FORM);
                    pd.put("orgName", vo.getReportCompanyName());
                    pageDataList.add(pd);
                }
            }
            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Collections.singletonList(FormTypeConstant.ZCGL_JZSGJGBA_FORM);
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id           主键
     * @param updateStatus 更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus) {
        try {
            JzsgjgbaEntity entity = getById(id);
            entity.setStatus(updateStatus);
            updateById(entity);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }
}
